<?php
// $Id: front.php 27 2010-11-16 12:49:54Z mjohnson60@gmail.com $


$main = 'front';

/**
 * front()
 * 
 * this function is called immediately after all variables have been loaded and all forms
 * have been validated and submitted
 * 
 * @param mixed $vars
 * @return void
 */
function front(&$vars)
{
	global $op;
	
	athena_add_styles('assets/css/style.css');
	athena_add_js('assets/js/jquery.js');
	
	if ($op == 'view')
	{
		athena_add_js('assets/js/selectable.table.js');
	}
	else
	{
		page_title('BugZapp Development Program');
	}
}

/**
 * front_preprender_page()
 * 
 * this function sets the content variable for the page.tpl.php template and any other data
 * such as page titles, etc.
 * 
 * This function also chooses which forms to display based on query string parameters
 * (ie. ?op=edit or ?op=add, etc.)
 * 
 * @param mixed $vars
 * @return void
 */
function front_prerender_page(&$vars)
{
	global $front_form, $op;
	
	if (!isset($front_form))
	{
		$front_form = front_default_form();
		
		if ($op == 'view' && isset($_GET['did']))
		{
			front_view_developer_form(array(
				'developer_list' => array(
					$_GET['did']
				), 
				'#direct' => TRUE
			));
		}
	}
	
	$vars['content'] = form_build($front_form, 'developers_list' . (empty($op) ? '' : '_' . $op));
}

/**
 * front_developer_inputs()
 * 
 * @return
 */
function front_developer_inputs()
{
	$result = db_query('SELECT * FROM developer WHERE did > 0 ORDER BY name ASC');
	
	$developers = array();
	while ($db_dev = db_fetch_array($result))
	{
		$dev = new Developer($db_dev);
		$developers[$dev->id()] = array(
			'#title' => $dev->name, 
			'#value' => $dev->id()
		);
	}
	
	if (empty($developers))
	{
		$developers[0] = array(
			'#title' => 'Please Add Developers', 
			'#attributes' => array(
				'disabled' => 'disabled'
			)
		);
	}
	
	return array(
		'#type' => 'select', 
		'#title' => 'Developers', 
		'#multiple' => TRUE, 
		'#options' => $developers, 
		'#attributes' => array(
			'class' => 'multiple'
		)
	);
}

/**
 * front_default_form()
 * 
 * This function returns the default form for the page (ie. the form that is rendered) with no 
 * query string parameters
 * 
 * in this case, this form lists developers and gives options to delete, add, edit, or view the developer's task lists
 * 
 * @return
 */
function front_default_form()
{
	$form_id = unique_id('developers-list');
	$form = array(
		
		'#id' => $form_id, 
		'#action' => base_path() . '?op=process', 
		'#method' => 'POST', 
		'#callback' => 'front_developers_list_submit', 
		'#inputs' => array(
			
			'developer_list' => front_developer_inputs(), 
			'button_container' => array(
				'#type' => 'html', 
				'#value' => '<div class="form-item-container">'
			), 
			'view_container' => array(
				'#type' => 'html', 
				'#value' => '<div class="form-item-wrapper">'
			), 
			'view' => array(
				
				'#type' => 'submit', 
				'#value' => 'View Task List', 
				'#id' => unique_id('view-task-list'), 
				'#attributes' => array(
					'class' => 'ui-button task-list', 
					'onclick' => "$('#" . $form_id . "').get(0).setAttribute('action', '" . base_path() . "?op=view');"
				), 
				'#prefix' => '<div class="form-item submit">', 
				'#suffix' => '<div class="small description">(Select only one developer)</div></div>'
			), 
			'view_container_close' => array(
				'#type' => 'html', 
				'#value' => '</div>'
			), 
			'edit_container' => array(
				'#type' => 'html', 
				'#value' => '<div class="form-item-wrapper">'
			), 
			'edit' => array(
				
				'#type' => 'submit', 
				'#value' => 'Edit Developer', 
				'#id' => unique_id('edit-developer'), 
				'#attributes' => array(
					'class' => 'ui-button edit-developer', 
					'onclick' => "$('#" . $form_id . "').get(0).setAttribute('action', '" . base_path() . "?op=edit');"
				), 
				'#suffix' => '<div class="small description">(Select one or more developers)</div>'
			), 
			'edit_container_close' => array(
				'#type' => 'html', 
				'#value' => '</div>'
			), 
			'submit_container' => array(
				'#type' => 'html', 
				'#value' => '<div class="form-item-wrapper">'
			), 
			'submit' => array(
				'#type' => 'submit', 
				'#value' => 'Add New Developer', 
				'#id' => unique_id('add-new-developer'), 
				'#attributes' => array(
					'class' => 'ui-button add-new-developer', 
					'onclick' => "$('#" . $form_id . "').get(0).setAttribute('action', '" . base_path() . "?op=add');"
				), 
				'#suffix' => '<div class="small description">(Select one or more developers)</div>'
			), 
			'submit_container_close' => array(
				'#type' => 'html', 
				'#value' => '</div>'
			), 
			'delete_container' => array(
				'#type' => 'html', 
				'#value' => '<div class="form-item-wrapper">'
			), 
			'delete' => array(
				
				'#type' => 'submit', 
				'#value' => 'Delete Developer', 
				'#id' => unique_id('delete-developer'), 
				'#attributes' => array(
					'class' => 'ui-button delete-developer', 
					'onclick' => "$('#" . $form_id . "').get(0).setAttribute('action', '" . base_path() . "?op=delete&subop=confirm');"
				), 
				'#suffix' => '<div class="small description">(Select one or more developers)</div>'
			), 
			'delete_container_close' => array(
				'#type' => 'html', 
				'#value' => '</div>'
			), 
			'button_container_close' => array(
				'#type' => 'html', 
				'#value' => '</div>'
			)
		)
	);
	
	return $form;
}

/**
 * front_developers_list_submit()
 * 
 * @param mixed $form_result
 * @return void
 */
function front_developers_list_submit(&$form_result)
{
	if (!empty($form_result['values']['submit']))
	{
		$values = $form_result['values'];
		
		switch ($values['submit'])
		{
			case 'View Task List' :
				if (isset($values['developer_list']) && count($values['developer_list']) > 0)
				{
					front_view_developer_form($values);
				}
				else
				{
					system_redirect(base_path());
				}
				
				break;
			case 'Edit Developer' :
				if (isset($values['developer_list']) && count($values['developer_list']) > 0)
				{
					front_edit_developer_form($values);
				}
				else
				{
					system_redirect(base_path());
				}
				
				break;
			case 'Add New Developer' :
				front_add_developer_form();
				
				break;
			case 'Delete Developer' :
				if (isset($values['developer_list']) && count($values['developer_list']) > 0)
				{
					front_delete_developer_confirmation_form($values);
				}
				else
				{
					system_redirect(base_path());
				}
				
				break;
		}
	}
}

/**
 * front_view_developer_form()
 * 
 * @param mixed $values
 * @param bool $reload
 * @return void
 */
function front_view_developer_form($values, $reload = FALSE)
{
	global $front_form;
	
	$did = $values['developer_list'][0];
	
	if (!empty($did) && (!isset($values['#direct']) || $values['#direct'] !== TRUE))
	{
		system_redirect(base_path() . '?op=view&did=' . $values['developer_list'][0]);
	}
	
	system_page_title('Developer Tasks');
	
	$form_id = unique_id('developer-task-list-view');
	$front_form = array(
		
		'#id' => $form_id, 
		'#action' => base_path() . '?op=view', 
		'#method' => 'POST', 
		'#callback' => 'front_view_developer_submit', 
		'#inputs' => array(
			
			'edit' => array(
				
				'#type' => 'submit', 
				'#value' => 'Edit Developer', 
				'#id' => unique_id('edit-developer'), 
				'#attributes' => array(
					'class' => 'ui-button edit-developer', 
					'onclick' => "$('#" . $form_id . "').get(0).setAttribute('action', '" . base_path() . "?op=edit&did=" . $did . "');"
				)
			), 
			'delete' => array(
				
				'#type' => 'submit', 
				'#value' => 'Delete Developer', 
				'#id' => unique_id('delete-developer'), 
				'#attributes' => array(
					'class' => 'ui-button delete-developer', 
					'onclick' => "$('#" . $form_id . "').get(0).setAttribute('action', '" . base_path() . "?op=delete&did=" . $did . "');"
				)
			)
		)
	);
	
	$result = db_query('SELECT description, status, tid FROM task WHERE did=%d ORDER BY status DESC', $did);
	
	$rows = array();
	while ($task = db_fetch_array($result))
	{
		$rows[] = array(
			
			'#cells' => array(
				'edit' => a(array(
					'#href' => base_path() . 'task?op=edit&tid=' . $task['tid'], 
					'#anchor' => 'Edit', 
					'#attributes' => array(
						'class' => 'action-link edit'
					)
				)), 
				'description' => $task['description'], 
				'status' => Task::status_string($task['status'])
			)
		);
	}
	
	if (empty($rows))
	{
		$rows[] = array(
			'#cells' => array(
				'no_results' => array(
					'#value' => '<h2 style="text-align:center;">This developer has no tasks assigned</h2>', 
					'#attributes' => array(
						'colspan' => 3
					)
				)
			)
		);
	}
	
	$table_id = unique_id('task-table');
	$task_table = array(
		'#attributes' => array(
			'id' => $table_id, 
			'border' => 1, 
			'cellspacing' => 0, 
			'cellpadding' => 8, 
			'class' => 'selectable data-list-table'
		), 
		'#rows' => $rows, 
		'#header' => array(
			'', 
			'Description', 
			'Status'
		)
	);
	
	$table = render('table', $task_table);
	$front_form['#prefix'] = $table;
}

/**
 * front_view_developer_submit()
 * 
 * @param mixed $form_result
 * @return void
 */
function front_view_developer_submit(&$form_result)
{
	if (isset($_GET['did']))
	{
		$form_result['values']['developers_list'] = array(
			$_GET['did']
		);
		front_developers_list_submit($form_result);
	}
	else
	{
		system_redirect(base_path());
	}
}

/**
 * front_edit_developer_form()
 * 
 * @param mixed $values
 * @return void
 */
function front_edit_developer_form($values, $reload = FALSE)
{
	global $front_form;
	
	$form_id = unique_id('developers-list-edit');
	$front_form = array(
		'#id' => $form_id, 
		'#action' => base_path() . '?op=save', 
		'#method' => 'POST', 
		'#validator' => 'front_edit_developer_validate', 
		'#callback' => 'front_edit_developer_submit'
	);
	$name_input = array(
		'#type' => 'textfield', 
		'#title' => 'Developer Name', 
		'#size' => 45
	);
	$email_input = array(
		'#type' => 'textfield', 
		'#title' => 'Developer Email', 
		'#size' => 45
	);
	
	$inputs = array();
	if ($reload)
	{
		foreach ($values['name'] as $did => $name)
		{
			$inputs['name[' . $did . ']'] = array_merge($name_input, array(
				'#value' => $values['name'][$did]
			));
			$inputs['email[' . $did . ']'] = array_merge($email_input, array(
				'#value' => $values['email'][$did]
			));
		}
	}
	else
	{
		$result = db_query('SELECT * FROM developer WHERE did IN (' . implode(', ', array_values($values['developer_list'])) . ') ORDER BY name ASC');
		
		while ($developer = db_fetch_array($result))
		{
			$inputs['name[' . $developer['did'] . ']'] = array_merge($name_input, array(
				'#value' => $developer['name']
			));
			$inputs['email[' . $developer['did'] . ']'] = array_merge($email_input, array(
				'#value' => $developer['email']
			));
		}
	}
	
	$front_form['#inputs'] = array_merge($inputs, array(
		'save' => array(
			'#type' => 'submit', 
			'#value' => 'Save', 
			'#attributes' => array(
				'onclick' => "$('#" . $form_id . "').get(0).setAttribute('action', '" . base_path() . "?op=save');"
			)
		), 
		'cancel' => array(
			'#type' => 'submit', 
			'#value' => 'Cancel', 
			'#attributes' => array(
				'onclick' => "$('#" . $form_id . "').get(0).setAttribute('action', '" . base_path() . "?op=edit&subop=cancel');"
			)
		)
	));
}

/**
 * front_edit_developer_validate()
 * 
 * @param mixed $form_result
 */
function front_edit_developer_validate(&$form_result)
{
	if (isset($form_result['values']['submit']))
	{
		switch ($form_result['values']['submit'])
		{
			case 'Save' :
				$reload = FALSE;
				
				if (!isset($form_result['values']['name']) || !isset($form_result['values']['email']))
				{
					$reload = TRUE;
					form_error('name', 'Please enter a valid name between 5 and 45 characters.');
					form_error('email', 'Please enter a valid email address.');
				}
				else
				{
					foreach ($form_result['values']['name'] as $did => $name)
					{
						if (!preg_match("/^[a-zA-Z'\.-\s]{5,45}$/", $form_result['values']['name'][$did]))
						{
							$reload = TRUE;
							form_error('name[' . $did . ']', 'Please enter a valid name between 5 and 45 characters.');
						}
						
						if (!isset($form_result['values']['email'][$did]) || !valid_email($form_result['values']['email'][$did]))
						{
							$reload = TRUE;
							form_error('email[' . $did . ']', 'Please enter a valid email address.');
						}
					}
				}
				
				if ($reload)
				{
					front_edit_developer_form($form_result['values'], $reload);
				}
				
				break;
			default :
				break;
		}
	}
}

/**
 * front_edit_developer_submit()
 * 
 * @param mixed $form_result
 * @return void
 */
function front_edit_developer_submit(&$form_result)
{
	if (isset($form_result['values']['submit']) && $form_result['values']['submit'] == 'Save')
	{
		foreach ($form_result['values']['name'] as $did => $name)
		{
			$email = $form_result['values']['email'][$did];
			
			$developer = new Developer(array(
				'did' => $did, 
				'name' => $name, 
				'email' => $email
			));
			
			$result = $developer->save();
			if ($result)
			{
				system_set_message('The developer <code>' . $developer->name . ' (' . $developer->email . ')</code> has successfully been updated.');
			}
		}
	}
}

/**
 * front_add_developer_confirmation_form()
 * 
 * @param mixed $values
 * @return void
 */
function front_add_developer_form($values = array())
{
	global $front_form;
	
	$form_id = unique_id('developers-list-add');
	$front_form = array(
		
		'#id' => $form_id, 
		'#action' => base_path() . '?op=add', 
		'#method' => 'POST', 
		'#validator' => 'front_add_developer_validate', 
		'#callback' => 'front_add_developer_submit', 
		'#inputs' => array(
			'name' => array(
				'#type' => 'textfield', 
				'#title' => 'Developer Name', 
				'#size' => 45
			), 
			'email' => array(
				'#type' => 'textfield', 
				'#title' => 'Developer Email', 
				'#size' => 45
			), 
			'create' => array(
				'#type' => 'submit', 
				'#value' => 'Create', 
				'#attributes' => array(
					'onclick' => "$('#" . $form_id . "').get(0).setAttribute('action', '" . base_path() . "?op=add');"
				)
			), 
			'cancel' => array(
				'#type' => 'submit', 
				'#value' => 'Cancel', 
				'#attributes' => array(
					'onclick' => "$('#" . $form_id . "').get(0).setAttribute('action', '" . base_path() . "?op=add&subop=cancel');"
				)
			)
		)
	);
	
	if (!empty($values))
	{
		$front_form['#inputs']['name']['#value'] = $values['name'];
		$front_form['#inputs']['email']['#value'] = $values['email'];
	}
}

/**
 * front_add_developer_validate()
 * 
 * @param mixed $form_result
 * @return void
 */
function front_add_developer_validate(&$form_result)
{
	if (isset($form_result['values']['submit']))
	{
		switch ($form_result['values']['submit'])
		{
			case 'Cancel' :
				
				break;
			case 'Create' :
				$reload = FALSE;
				
				if (!isset($form_result['values']['name']) || !preg_match("/^[a-zA-Z\.'-\s]{5,45}$/", $form_result['values']['name']))
				{
					$reload = TRUE;
					form_error('name', 'Please enter a valid name between 5 and 45 characters.');
				}
				
				if (!isset($form_result['values']['email']) || !valid_email($form_result['values']['email']))
				{
					$reload = TRUE;
					form_error('email', 'Please enter a valid email address.');
				}
				
				if ($reload)
				{
					front_add_developer_form($form_result['values']);
				}
				
				break;
		}
	}
}

/**
 * front_add_developer_confirmation_submit()
 * 
 * @param mixed $form_result
 * @return void
 */
function front_add_developer_submit(&$form_result)
{
	if (isset($form_result['values']['submit']) && $form_result['values']['submit'] == 'Create')
	{
		$developer = new Developer(array(
			'name' => $form_result['values']['name'], 
			'email' => $form_result['values']['email']
		));
		
		$result = $developer->save();
		if ($result)
		{
			system_set_message('The following developer was successfully created: <code>' . $developer->name . ' (' . $developer->email . ')' . '</code>');
		}
	}
}

/**
 * front_delete_developer_confirmation_form()
 * 
 * @param mixed $values
 * @return void
 */
function front_delete_developer_confirmation_form($values)
{
	global $front_form;
	
	$form_id = unique_id('developers-list-delete');
	$front_form = array(
		'#id' => $form_id, 
		'#action' => base_path() . '?op=delete', 
		'#method' => 'POST', 
		'#validator' => 'front_delete_developer_confirmation_validate', 
		'#callback' => 'front_delete_developer_confirmation_submit', 
		'#inputs' => array(
			'developer_list' => front_developer_inputs()
		)
	);
	
	$developer_list = $values['developer_list'];
	$_SESSION['front']['developer_list'] = array();
	
	$confirmation = '<ul class="confirmation">';
	foreach ($developer_list as $did)
	{
		$front_form['#inputs']['developer_list']['#options'][$did]['#selected'] = TRUE;
		
		$_SESSION['front']['developer_list'][] = $did;
		$name = db_result(db_query('SELECT name FROM developer WHERE did=%d', $did));
		$confirmation .= '<li><em>' . $name . '</em></li>';
	}
	$confirmation .= '</ul>';
	
	$front_form['#inputs'] += array(
		'confirm' => array(
			'#title' => 'Are you sure you want to delete the following developer(s)?' . $confirmation, 
			'#type' => 'checkbox', 
			'#description' => 'This developer will be completely erased from the system.', 
			'#value' => 1, 
			'#checked' => FALSE
		), 
		'submit' => array(
			'#type' => 'submit', 
			'#value' => 'Delete', 
			'#attributes' => array(
				'onclick' => "$('#" . $form_id . "').get(0).setAttribute('action', '" . base_path() . "?op=delete');"
			)
		), 
		'cancel' => array(
			'#type' => 'submit', 
			'#value' => 'Cancel', 
			'#attributes' => array(
				'onclick' => "$('#" . $form_id . "').get(0).setAttribute('action', '" . base_path() . "?op=delete&subop=cancel');"
			)
		)
	);
	
	if ($error = form_error('confirm'))
	{
		$inputs['confirm']['#attributes'] = array(
			'class' => 'error'
		);
		system_set_message($error, 'error');
	}
}

/**
 * front_delete_developer_validate()
 * 
 * @param mixed $form_result
 * @return void
 */
function front_delete_developer_confirmation_validate(&$form_result)
{
	switch ($form_result['values']['submit'])
	{
		case 'Delete' :
			$confirmation_form = FALSE;
			if (!isset($form_result['values']['confirm']) || $form_result['values']['confirm'] != 1)
			{
				form_error('confirm', 'Please confirm that you would like to delete a developer, or click Cancel.');
				$confirmation_form = TRUE;
			}
			
			$developers = $form_result['values']['developer_list'];
			$stored_dids = $_SESSION['front']['developer_list'];
			unset($_SESSION['front']['developer_list']);
			
			foreach ($developers as $developer)
			{
				if (!in_array($developer, $stored_dids))
				{
					form_error('developer_list[]', 'Your selection has changed.');
					$confirmation_form = TRUE;
					
					break;
				}
				
				if ($developer == 0 || $developer == 1)
				{
					form_error('developer_list[]', 'You cannot delete the Lead Developer');
					$confirmation_form = TRUE;
				}
			}
			
			if ($confirmation_form)
			{
				front_delete_developer_confirmation_form($form_result['values']);
			}
			
			break;
		case 'Cancel' :
			break;
	}
}

/**
 * front_delete_developer_submit()
 * 
 * @param mixed $form_result
 * @return void
 */
function front_delete_developer_confirmation_submit(&$form_result)
{
	if ($form_result['values']['submit'] == 'Delete')
	{
		$developers = $form_result['values']['developer_list'];
		if (count($developers) > 0)
		{
			$did_str = str_repeat(', %d', count($developers) - 1);
			$did_str = '%d' . $did_str;
			
			$names = array();
			$result = db_query('SELECT name FROM developer WHERE did IN (' . $did_str . ')', $developers);
			while ($name = db_result($result))
			{
				$names[] = $name;
			}
			
			$names = implode(', ', $names);
			
			$result = db_query('DELETE FROM developer WHERE did IN (' . $did_str . ')', $developers);
			$relational_result = db_query('UPDATE task SET did=0 WHERE did IN (' . $did_str . ')', $developers);
			if ($result && $relational_result)
			{
				system_set_message('The following developers were successfully deleted: <code>' . $names . '</code>');
			}
		}
	}
}






